import Singleton from "../../framework/scripts/base/Singleton"
import EventMgr from "../../framework/scripts/manager/EventMgr"
import TimerMgr from "../../framework/scripts/manager/TimerMgr"
import TopBlock from "../../framework/scripts/view/TopBlock"
import Constants from "../Constants"
import AccountCtrl from "../controller/AccountCtrl"
import NetMgr, { NetEvent } from "../net/NetMgr"
import Packet from "../net/Packet"
import AccountHeart from "../pb/AccountHeart"
import Msg from "../pb/Msg"
import SystemDisconnect from "../pb/SystemDisconnect"
import SystemError from "../pb/SystemError"
import TimeUtil from "../util/TimeUtil"


export default class GameMgr extends Singleton {
    public static get inst() {
        return this.getInstance<GameMgr>()
    }

    constructor() {
        super()

        this.init()
    }

    private _reconnectTimes = 0


    public connect() {
        TopBlock.show()

        if (NetMgr.inst.connect(Constants.wsUrl)) {
            AccountCtrl.inst.onNetOpen()
        }
    }

    public onLoginOk() {
        TopBlock.hide()
        this._reconnectTimes = 0
    }


    private init() {
        EventMgr.on(NetEvent.Open, this.onNetOpen, this)
        EventMgr.on(NetEvent.Error, () => { }, this)
        EventMgr.on(NetEvent.Close, this.onNetClose, this)

        this.initHeart()

        NetMgr.inst.on(Msg.SYSTEM_TIME, () => { }, this)
        NetMgr.inst.on(Msg.SYSTEM_ERROR, (_packetId: number, packet: Packet) => {
            TopBlock.hide()
            const ret = SystemError.decode(packet)
            console.error('服务端返回错误:', ret.code)
        }, this)
        NetMgr.inst.on(Msg.SYSTEM_DISCONNECT, (_packetId: number, packet: Packet) => {
            TopBlock.hide()
            const ret = SystemDisconnect.decode(packet)
            console.error('服务端关闭链接:', ret.code)
        }, this)

        AccountCtrl.inst
    }

    private initHeart() {
        const packet = new AccountHeart().encode()

        TimerMgr.inst.add(2000, () => {
            if (!NetMgr.inst.isConnect) return

            NetMgr.inst.send(packet)
        }, this, 0)
    }


    private onNetOpen() {
        console.log('GameMgr 网络链接成功')

        TopBlock.show()
        NetMgr.inst.sendText('game-------------------')

        AccountCtrl.inst.onNetOpen()
    }

    private async onNetClose() {
        console.log('GameMgr 网络链接关闭')

        TopBlock.show()
        await TimeUtil.sleep(1000)

        this._reconnectTimes++
        cc.error(`开始第 ${this._reconnectTimes} 次重连`)

        this.connect()
    }
}
